(* File MicroC/Absyn.fs
   Abstract syntax of micro-C, an imperative language.
   sestoft@itu.dk 2009-09-25

   Must precede Interp.fs, Comp.fs and Contcomp.fs in Solution Explorer
 *)

module Absyn

type typ =
  | TypeInt   //=
  | TypeShort //=
  | TypeLong  //=                        
  | TypeChar  //=
  | TypeFloat //=
  | TypeDouble //=
  | TypeString //=
  | TypeBoolean //=                         
  | TypeArray of typ * int option         (* Array type                  *) //=
  | TypePoint of typ                      (* Pointer type                *) //=

and expr =
    | Access of access (* x    or  *p    or  a[e]     *) //访问左值（右值）
    | Assign of access * expr (* x=e  or  *p=e  or  a[e]=e   *)
    | Addr of access (* &x   or  &*p   or  &a[e]    *)
    | ConstInt of int   (* Constant      *) //=
    | ConstString of string (*constant string*)//=
    | ConstFloat of float32 (*constant float*)//=
    | ConstDouble of double  (*constant float*)//=
    | ConstChar of char (*constant char*) //=
    | ConstLong of int64  (*constant long*) //=
    | Prim1 of string * expr (* Unary primitive operator    *)
    | Prim2 of string * expr * expr (* Binary primitive operator   *)
    | Prim3 of expr * expr * expr       (* triary primitive operator   *) //=
    | Andalso of expr * expr (* Sequential and              *)
    | Orelse of expr * expr (* Sequential or               *)
    | Call of string * expr list (* Function call f(...)        *)

and access =
    | AccVar of string (* Variable access        x    *)
    | AccDeref of expr (* Pointer dereferencing  *p   *)
    | AccIndex of access * expr (* Array indexing         a[e] *)

and stmt =
    | If of expr * stmt * stmt (* Conditional                 *)
    | While of expr * stmt (* While loop                  *)
    | For of stmtordec * expr * expr * stmt //=
    | Switch of expr * stmt list //=
    | Case of expr * stmt //=
    | Expr of expr (* Expression statement   e;   *)
    | Return of expr option (* Return from method          *)
    | Block of stmtordec list (* Block: grouping and scope   *)
    | Break //=
    | Continue //=

// 语句块内部，可以是变量声明 或语句的列表

and stmtordec =
    | Dec of typ * string (* Local variable declaration  *)
    | DeclareAndAssign of typ * string * expr //=
    | Stmt of stmt (* A statement                 *)

// 顶级声明 可以是函数声明或变量声明
and topdec =
    | Fundec of typ option * string * (typ * string) list * stmt
    | Vardec of typ * string
    | VardecAndAssign of typ * string * expr //=

// 程序是顶级声明的列表
and program = Prog of topdec list
